#include "ezfb.h"
#include "basic.h"

VOID		EZFBAPI		SetPixel(
						LONG x,
						LONG y,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);
	__SetPixel(lpSurface, x, y, crColor);
}

COLORREF	EZFBAPI		GetPixel(
						LONG x,
						LONG y,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);
	return __GetPixel(lpSurface, x, y);
}

STATIC INLINE
LONG		EZFBAPI		AbsL(
						LONG lnValue
						) {
	return (lnValue > 0) ? (lnValue) : (-lnValue);
}

VOID		EZFBAPI		DrawLine(
						LONG x1,
						LONG y1,
						LONG x2,
						LONG y2,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);
	BOOL isSteep = AbsL(y2 - y1) > AbsL(x2 - x1);
	LONG lnTemp;
	if (isSteep) {
		if (y1 > y2) {
			lnTemp = x1; x1 = x2; x2 = lnTemp;
			lnTemp = y1; y1 = y2; y2 = lnTemp;
		}
		LONG dy	= y2 - y1;
		LONG dx = AbsL(x2 - x1);
		LONG error	= -(dy >> 1);
		LONG y = y1, x = x1;
		LONG xstep = (x1 < x2) ? (1) : (-1);
		while (y <= y2) {
			__SetPixel(lpSurface, x, y, crColor);
			error += dx;
			if (error > 0) {
				x += xstep;
				error -= dy;
			}
			++ y;
		}
	} else {
		if (x1 > x2) {
			lnTemp = x1; x1 = x2; x2 = lnTemp;
			lnTemp = y1; y1 = y2; y2 = lnTemp;
		}
		LONG dx	= x2 - x1;
		LONG dy = AbsL(y2 - y1);
		LONG error = -(dx >> 1);
		LONG x = x1, y = y1;
		LONG ystep = (y1 < y2) ? (1) : (-1);
		while (x <= x2) {
			__SetPixel(lpSurface, x, y, crColor);
			error += dy;
			if (error > 0) {
				y += ystep;
				error -= dx;
			}
			++ x;
		}
	}
}

VOID		EZFBAPI		DrawRect(
						LONG left,
						LONG top,
						LONG right,
						LONG bottom,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);
	if (left == right || top == bottom)
		return;
	if (left > right) {
		LONG temp = left; left = right; right = temp;
	}
	if (top > bottom) {
		LONG temp = top; top = bottom; bottom = temp;
	}
	LONG x, y;
	for (x = left; x < right; ++ x) {
		__SetPixel(lpSurface, x, top, crColor);
		__SetPixel(lpSurface, x, bottom - 1, crColor);
	}
	for (y = top; y < bottom; ++ y) {
		__SetPixel(lpSurface, left, y, crColor);
		__SetPixel(lpSurface, right - 1, y, crColor);
	}
}

VOID		EZFBAPI		FillRect(
						LONG left,
						LONG top,
						LONG right,
						LONG bottom,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);
	if (left == right || top == bottom)
		return;
	if (left > right) {
		LONG temp = left; left = right; right = temp;
	}
	if (top > bottom) {
		LONG temp = top; top = bottom; bottom = temp;
	}
	LONG x, y;
	for (y = top; y < bottom; ++ y) {
		for (x = left; x < right; ++ x) {
			__SetPixel(lpSurface, x, y, crColor);
		}
	}
}

VOID		EZFBAPI		DrawCircle(
						LONG x0,
						LONG y0,
						LONG r,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);

	LONG x = 0, y = r;
	LONG p = 1 - r;

	while (x <= y) {
		__SetPixel(lpSurface, x0 + x, y0 + y, crColor);
		__SetPixel(lpSurface, x0 - x, y0 + y, crColor);
		__SetPixel(lpSurface, x0 + x, y0 - y, crColor);
		__SetPixel(lpSurface, x0 - x, y0 - y, crColor);
		
		__SetPixel(lpSurface, x0 + y, y0 + x, crColor);
		__SetPixel(lpSurface, x0 - y, y0 + x, crColor);
		__SetPixel(lpSurface, x0 + y, y0 - x, crColor);
		__SetPixel(lpSurface, x0 - y, y0 - x, crColor);

		++ x;
		if (p < 0)
			p += ((x) << 1) + 1;
		else {
			-- y;
			p += ((x - y) << 1) + 1;
		}
	}
}

VOID		EZFBAPI		FillCircle(
						LONG x0,
						LONG y0,
						LONG r,
						COLORREF crColor,
						DWORD dwFlag
						) {
	LPSURFACE lpSurface	= (dwFlag & DF_BUFFER) ? (&sfBuffer) : (&sfScreen);

	LONG x = 0, y = r, t;
	LONG p = 1 - r;

	while (x <= y) {
		for (t = x0 - x; t <= x0 + x; ++ t) {
			__SetPixel(lpSurface, t, y0 + y, crColor);
			__SetPixel(lpSurface, t, y0 - y, crColor);
		}
		for (t = x0 - y; t <= x0 + y; ++ t) {
			__SetPixel(lpSurface, t, y0 + x, crColor);
			__SetPixel(lpSurface, t, y0 - x, crColor);
		}

		++ x;
		if (p < 0)
			p += ((x) << 1) + 1;
		else {
			-- y;
			p += ((x - y) << 1) + 1;
		}
	}
}
